#include <SceneViewer.h>
#include <osgViewer/ViewerEventHandlers>
//#include <ModelMatrixCallBack.h>
#include <list>
SceneViewer* SceneViewer::_instance = NULL;
SceneViewer::SceneViewer()
{
	_viewer = new osgViewer::Viewer;

	_viewer->addEventHandler(new osgViewer::StatsHandler);
	_viewer->addEventHandler(new osgViewer::WindowSizeHandler);

	//_viewer->setSceneData(this);

	_switch_camera_manipulator = new SwitchCameraManipulator;
	_viewer->setCameraManipulator(_switch_camera_manipulator);

	

	_call_back_node_dummy = new osg::Group;
	_call_back_node_dummy->setDataVariance(osg::Object::DataVariance::DYNAMIC);
	addChild(_call_back_node_dummy);
    setName("SceneViewerRootNode");
	_call_back_node_dummy->setName("Call Back Node Dummy");

	_model_root = new osg::Group;
	_model_root->setName("SceneViewModelRoot");
	addChild(_model_root);

	osg::DisplaySettings::instance()->setMinimumNumStencilBits(1);
	unsigned int clearMask = _viewer->getCamera()->getClearMask();
	_viewer->getCamera()->setClearMask(clearMask | GL_STENCIL_BUFFER_BIT);
	_viewer->getCamera()->setClearStencil(0);

    _viewer->getUpdateVisitor()->setTraversalMask(0x2);
}

SceneViewer::~SceneViewer()
{

}
// 
// void SceneViewer::addModel( osg::ref_ptr<ModelBase> scene_model )
// {
// 	addChild(scene_model->getSwitch());
// 
// 	_model_base_vector.push_back(scene_model);
// }
/**/
//void SceneViewer::addModel( osg::ref_ptr<ModelBase> scene_model, bool enable_reflection /*= false*/ )
//{
//	if (enable_reflection == false)
//	{
//		_model_root->addChild(scene_model->getSwitch());
//		_model_base_vector.push_back(scene_model);
//	}
//	else
//	{

//			_model_root->addChild(scene_model->getSwitch());
//			_model_base_vector.push_back(scene_model);
//	}
//}



//void SceneViewer::pushBackModel( osg::ref_ptr<ModelBase>  scene_model)
//{
//	_model_base_vector.push_back(scene_model);
//}
SceneViewer* SceneViewer::instance()
{
	if (_instance == NULL)
	{
		_instance = new SceneViewer();
	}
	return _instance;
}

osg::ref_ptr<osgViewer::Viewer> SceneViewer::getViewer()
{
	return _viewer;
}

//osg::ref_ptr<ModelBase> SceneViewer::getModelBase( int index_of_vector )
//{
//	return _model_base_vector[index_of_vector];
//}

//osg::ref_ptr<ModelBase> SceneViewer::getModelBase( const std::string& model_base_name )
//{
//	int i = 0;
//	for (i = 0; i < _model_base_vector.size(); i++)
//	{
//		if (model_base_name.compare(_model_base_vector[i]->getName()) == 0)
//		{
//			return _model_base_vector[i];
//		}
//	}
//	return NULL;
//}


//int SceneViewer::getModelBaseVectorSize()
//{
//	return _model_base_vector.size();
//}


//std::string SceneViewer::getModelBaseName( int index_of_vector )
//{
//	std::string model_base_name;
//	if (index_of_vector < getModelBaseVectorSize())
//	{
//		model_base_name = _model_base_vector[index_of_vector]->getName();
//	}
//	return model_base_name;
//}


osg::ref_ptr<SwitchCameraManipulator> SceneViewer::getSwitchCameraManipulator()
{
	return _switch_camera_manipulator;
}

void SceneViewer::addCallBack( osg::ref_ptr<osg::NodeCallback> call_back )
{
	osg::ref_ptr<osg::Node> node = new osg::Node;
	node->setUpdateCallback(call_back);
	//_call_back_node_dummy.push_back(node);
	_call_back_node_dummy->addChild(node);
	node->setDataVariance(osg::Object::DataVariance::DYNAMIC);
}

void SceneViewer::removeCallBack(const std::string& name)
{
	int i = 0;
	for (i = 0; i<_call_back_node_dummy->getNumChildren(); i++)
	{
		osg::Node* node_ptr = _call_back_node_dummy->getChild(i);
		if (node_ptr->getUpdateCallback()->getName().compare(name) == 0)
		{
			_call_back_node_dummy->removeChild(node_ptr);
			return;
		}
	}
	
	
}

void SceneViewer::setUpSceneData()
{
	_viewer->setSceneData(this);
	_viewer->setCameraManipulator(_switch_camera_manipulator);
}

//void SceneViewer::callAllModelBaseCallBackOperatorFunction()
//{
//	int i;
//	for (i = 0; i < _model_base_vector.size(); i++)
//	{
//		ModelMatrixCallBack* call_back = _model_base_vector[i]->getModelMatrixCallBack();

//		if (call_back != NULL)
//		{
//			call_back->notify();
//		}
//	}
//}

osg::ref_ptr<osg::Group> SceneViewer::getModelRoot()
{
	return _model_root;
}


void SceneViewer::setModelRoot( osg::ref_ptr<osg::Group> model_root )
{
    _model_root = model_root;
}

void SceneViewer::clearModelRoot()
{
    _model_root->removeChildren(0, _model_root->getNumChildren());
}


int SceneViewer::getEventHandlerSize()
{
	return _viewer->getEventHandlers().size();
}

osg::ref_ptr<osgGA::GUIEventHandler> SceneViewer::getEventHandler( int index )
{
	if (index < getEventHandlerSize())
	{
		osgViewer::View::EventHandlers handlers = _viewer->getEventHandlers();
		int i = 0;
		std::list<osg::ref_ptr<osgGA::GUIEventHandler>>::iterator it;  
		for(it=handlers.begin();it!=handlers.end();it++)  
		{
			if (i == index)
			{
				return *it;
			}
			i++;
			
		}  
	}
	return NULL;
}

osg::ref_ptr<osg::Object> SceneViewer::getEventHandlerObject( int index )
{
	osg::ref_ptr<osgGA::GUIEventHandler> handler = getEventHandler(index);
	osg::ref_ptr<osg::Object> object_ptr = dynamic_cast<osg::Object*>(handler.get());
    return object_ptr;
}

void SceneViewer::setUpdateVisitorMask(osg::Node::NodeMask mask)
{
    _viewer->getUpdateVisitor()->setTraversalMask(mask);
}

osg::NodeVisitor *SceneViewer::getUpdateVisitor()
{
    return _viewer->getUpdateVisitor();
}
